package com.tmsps.common.util.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.Map;


/**
 * @Title:  JWTUtil.java
 * @Package com.xingge.weixin.util
 * @description JSON Web Token Util
 * @author zhangwei
 * @date   2020/05/16
 * @version  v1.0
 * @Copyright: 2020 TMSPS All rights reserved.
 */
@Slf4j
public class JWTUtil {
	private JWTUtil() {
	}
	/**
	 *  使用HMAC256算法加密
	 */
	static final Algorithm algorithm = Algorithm.HMAC256(JWTConstant.JWT_SECRET);
	
	
	/**
	 * @Title: generaToken
	 * @description 生成Token
	 * @authorzhangwei
	 * @date 2020/05/16
	 * @param: @param expTime 过期时间，这个是按照签发时间向后推迟的毫秒数
	 * @param: @param jwtId 业务中唯一的标识ID
	 * @param: @param claims 自定义的数据 MAP
	 * @param: @return      
	 * @return: String      
	 * @throws
	 * iss: jwt签发者 
	 * sub: jwt所面向的用户
	 * aud: 接收jwt的一方
	 * exp: jwt的过期时间，这个过期时间必须要大于签发时间
	 * nbf: 定义在什么时间之前，该jwt都是不可用的
	 * iat: jwt的签发时间
	 * jti: jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击。
	 */
	public static String generaToken(Long expTime, String jwtId, Map<String, Object> claims) {
		Long now = System.currentTimeMillis();
		String token = JWT.create()
				.withIssuer(JWTConstant.JWT_ISSUER)
				.withSubject(JWTConstant.JWT_SUBJECT)
				.withIssuedAt(new Date(now))
				.withExpiresAt(new Date(now + expTime*1000L))
				.withJWTId(jwtId)
				.withClaim(JWTConstant.JWT_DEFINITION, claims)
				.sign(algorithm);
		return token;
	}
	
	/**
	 * @Title: verifier
	 * @description 验证JWT是否有效，使用签发者比对，如果时间过期或者未到签发时间或者其他伪造token会默认报错返回false
	 * @authorzhangwei
	 * @date 2020/05/16
	 * @param: @param token
	 * @param: @return      
	 * @return: boolean      
	 * @throws
	 */
	public static boolean verifier(String token) {
		try {
			return JWT.require(algorithm).build().verify(token).getIssuer().equals(JWTConstant.JWT_ISSUER);
		} catch (Exception e) {
			log.error(e.getMessage());
			return false;
		}
	}
	
	/**
	 * @Title: getJTI
	 * @description 获取业务唯一标识
	 * @authorzhangwei
	 * @date 2020/05/16
	 * @param: @param token
	 * @param: @return      
	 * @return: String      
	 * @throws
	 */
	public static String getJTI(String token) {
		return JWT.decode(token).getId();
	}
	
	/**
	 * @Title: getValue
	 * @description 获取自定义的数值
	 * @authorzhangwei
	 * @date 2020/05/16
	 * @param: @param token
	 * @param: @param key
	 * @param: @return      
	 * @return: Object      
	 * @throws
	 */
	public static Object getValue(String token, String key) {
		return JWT.decode(token).getClaim(JWTConstant.JWT_DEFINITION).asMap().get(key);
	}

	/**
	 * @Title: getAllValue
	 * @description 获取全部自定义的数值
	 * @authorzhangwei
	 * @date 2020/05/16
	 * @param: @param token
	 * @return: Map<String, Object>
	 * @throws
	 */
	public static Map<String, Object> getAllValue(String token) {
		return JWT.decode(token).getClaim(JWTConstant.JWT_DEFINITION).asMap();
	}
}
